TIL (JPA 강의 수강)

Posted by ChaelinJ on January 08, 2022
  • 강의명 : 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
  • 강의 회차: 엔티티 설계시 주의점
  • 강의 내용
    1. 실무에선 setter의 사용을 최소화 하는 것이 좋다. 변경을 통제하기 어려워 유지보수가 쉽지 않다.

    2. 모든 연관관계는 지연로딩으로 설정

       @ManyToOne(fetch = FetchType.LAZY)
       @OneToOne(fetch = FetchType.LAZY)
      

      즉시로딩(FetchType.EAGER)인 경우, 엔티티 조회시 연관된 데이터를 다 조회하기 때문에 성능 문제가 발생한다.

      OneToOne, ManyToOne의 경우 default가 EAGER이기 때문에 명시적으로 설정해주어야 한다.

      연관된 데이터를 조회하는 경우, FetchType.JOIN이나 엔터티 그래프 기능을 사용할 수 있다.

      • EAGER: Left Outter Join
      • JOIN: Left Inner Join
    3. 즉시 로딩시 발생하는 N+1 문제 한 엔티티 조회시, 연관된 객체에 대해 조인으로 조회하는 것이 아니라 조회된 N개의 row 각각에 대해 다시 쿼리를 생성/수행하기 때문에 총 N+1번의 쿼리를 수행한다.

    4. 컬렉션 초기화 필드에서 바로 초기화 하는 것이 안전
      • NPE
      • Hibernate의 내부 로직에서 엔티티를 Persist(영속화)하면서 컬렉션을 한 번 감싸서 hibernate 내장 컬렉션으로 변경을 하기 때문에 추후에 set으로 컬렉션을 바꿔버리면 hibernate의 메커니즘대로 돌아가지 않아 오류가 발생할 수 있다.
    5. Table, Column명
      • 스프링 부트 신규 설정에 의해 카멜 케이스로 설정한 엔티티 명이 언더스코어( _ )로 변경되어 저장된다.
      • 대문자 -> 소문자
      • . -> _

      커스텀 가능하나 위의 규칙이 기본 세팅

      커스텀은 SpringPhysicalNamingStrategy 코드를 수정해 변경할 수 있다.

      • 논리명: 명시가 안 되어 있을 시에 적용되는 룰
      • 물리명: 모든 명칭에 적용 (명시, 명시x)
    6. Cascade Order 엔티티에 다음과 같이 설정된 경우, orderItem을 저장/삭제를 각각 persist하지 않고 order만 persist해도 연결되어 저장/삭제가 된다.

       @OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
       private List<OrderItem> orderItems = new ArrayList<>();
      
    7. 연관관계 편의 method 연관관계에서 DB에 저장하기 위해선 연관관계의 주인에만 저장하면 되나, 객체를 활용하기 위해선 양쪽 객체 모두에 저장하는 것이 활용적이다.

      엔티티 setter에서 한 쪽에 setting하면 연관관계가 있는 엔티티에도 값을 설정하도록 한다.

      양방향 연관관계 편의 method는 핵심적으로 controll하는 쪽에 있으면 좋다.

       public void setMember(Member member){
           this.member = member;
           member.getOrders().add(this);
       }
      

      Order 객체에 member를 저장하면서 동시에 해당 member에도 order 객체를 추가한다.